package com.rerun.common.config;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.amqp.support.converter.MessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.support.RetryTemplate;

import java.io.IOException;
import java.util.ResourceBundle;

/**
 * The type Rabbit mq config.
 *
 * @author dax.
 * @version v1.0
 * @since 2017 /11/7 15:14
 */
@Configuration
public class RabbitMqConfig {

    private static final Logger log = LoggerFactory.getLogger("RabbitMQ");
    private static final ResourceBundle RABBITMQ_CONFIG = ResourceBundle.getBundle("properties/rabbitmq-direct");


    /**
     * 配置基础连接信息.
     *
     * @return the connection factory
     * @throws IOException the io exception
     */

    private ConnectionFactory connectionFactory() throws IOException {
        log.info("initializing rabbitmq connection");
        CachingConnectionFactory connectionFactory = new CachingConnectionFactory(
                RABBITMQ_CONFIG.getString("rabbitmq.host"));
        connectionFactory.setPort(Integer.valueOf(RABBITMQ_CONFIG.getString("rabbitmq.port")) );
        connectionFactory.setUsername(RABBITMQ_CONFIG.getString("rabbitmq.username"));
        connectionFactory.setPassword(RABBITMQ_CONFIG.getString("rabbitmq.password"));
        return connectionFactory;
    }


    /**
     * 在配置了多个ConnectionFactory的情况下，需要配置RabbitAdmin，否则无法自动在rabbitmq服务器中注册交换机队列等.
     *
     * @return the rabbit admin
     * @throws IOException the io exception
     */
    @Bean
    public RabbitAdmin rabbitAdmin() throws IOException {
        return new RabbitAdmin(connectionFactory());
    }

    /**
     * 配置 生产者Template.
     *
     * @return the rabbit template
     * @throws IOException the io exception
     */
    @Bean
    public RabbitTemplate rabbitTemplate() throws IOException {
        RabbitTemplate rabbitTemplate = new RabbitTemplate();
        rabbitTemplate.setConnectionFactory(connectionFactory());

        ExponentialBackOffPolicy exponentialBackOffPolicy=new ExponentialBackOffPolicy();
        exponentialBackOffPolicy.setInitialInterval(Long.valueOf(RABBITMQ_CONFIG.getString("rabbitmq.backOffPolicy.initialInterval")) );
        exponentialBackOffPolicy.setMaxInterval(Long.valueOf(RABBITMQ_CONFIG.getString("rabbitmq.backOffPolicy.maxInterval")));
        exponentialBackOffPolicy.setMultiplier(Double.valueOf(RABBITMQ_CONFIG.getString("rabbitmq.backOffPolicy.multiplier") ));
        // retryTemplate为连接失败时的重发队列所用的template
        RetryTemplate retryTemplate=new RetryTemplate();
        retryTemplate.setBackOffPolicy( exponentialBackOffPolicy);

        rabbitTemplate.setRetryTemplate(retryTemplate);
        //配置生产者信息转换器，封装发送信息的格式
        MessageConverter jacksonConverter= new Jackson2JsonMessageConverter();
        rabbitTemplate.setMessageConverter(jacksonConverter);
        return rabbitTemplate;
    }

    /**
     * 消息监听容器.
     *
     * @return the simple message listener container
     * @throws IOException the io exception
     */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() throws IOException {
        SimpleMessageListenerContainer listenerContainer=new SimpleMessageListenerContainer();
        listenerContainer.setConnectionFactory(connectionFactory());
       return listenerContainer;
    }



}
